package gov.fema.hazus.bdc.server.servlet.tasks;

import gov.fema.hazus.bdc.server.servlet.DAO;
import gov.fema.hazus.bdc.shared.entity.AEBMResults;
import gov.fema.hazus.bdc.shared.entity.Address;
import gov.fema.hazus.bdc.shared.entity.Bracing;
import gov.fema.hazus.bdc.shared.entity.Building;
import gov.fema.hazus.bdc.shared.entity.Capacity;
import gov.fema.hazus.bdc.shared.entity.Contact;
import gov.fema.hazus.bdc.shared.entity.EarthquakeBuildingDesign;
import gov.fema.hazus.bdc.shared.entity.EarthquakeHazard;
import gov.fema.hazus.bdc.shared.entity.EarthquakeSecondaryCharacteristics;
import gov.fema.hazus.bdc.shared.entity.Economy;
import gov.fema.hazus.bdc.shared.entity.FloodBasement;
import gov.fema.hazus.bdc.shared.entity.FloodBuildingDesign;
import gov.fema.hazus.bdc.shared.entity.FloodHazard;
import gov.fema.hazus.bdc.shared.entity.Location;
import gov.fema.hazus.bdc.shared.entity.ManufacturedHousing;
import gov.fema.hazus.bdc.shared.entity.Roof;
import gov.fema.hazus.bdc.shared.entity.User;
import gov.fema.hazus.bdc.shared.entity.WallsAndOpenings;
import gov.fema.hazus.bdc.shared.entity.WindBuildingDesign;
import gov.fema.hazus.bdc.shared.entity.WindHazard;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Scanner;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.google.appengine.api.labs.taskqueue.Queue;
import com.google.appengine.api.labs.taskqueue.QueueFactory;
import com.google.appengine.api.labs.taskqueue.TaskOptions;
import com.google.appengine.api.labs.taskqueue.TaskOptions.Method;
import com.google.inject.Singleton;

@Singleton
public class TaskQueueLoadUsersObjectify extends HttpServlet {

	public static final String TASK_PATH = "/task/objectify/users/load";

	private final Logger logger = Logger.getLogger(TaskQueueLoadUsersObjectify.class);
    private Cache cache;

    private DAO dao = new DAO();
    
    public void init(ServletConfig config) throws ServletException {

        // Store the ServletConfig object and log the initialization
        super.init(config);
        logger.debug("Initializing servlet");
        
        try {
        	logger.debug("Initializing cache");
        	cache = CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
        } catch (CacheException e) {
            logger.debug("Could not setup cache");
        }
        
    }
    
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
	 throws ServletException, IOException {
		
		String lineNum = req.getParameter("l");
		int index = Integer.parseInt(lineNum);
		logger.debug("Parse index:" + index);
		
		ArrayList<String> out = (ArrayList<String>) cache.get("csv-user");
		logger.debug("Index ("+index+") from out=" + out.get(index));
		
		String line = out.get(index);
		String[] parts = line.split(",");
		
		try {
			
			User user = new User();
			
			String username = parseFieldAsString(parts[0]);
			String password = parseFieldAsString(parts[1]);
			String admin = parseFieldAsString(parts[2]);
			
			user.setUsername(username);
			user.setPassword(password);
			if(admin.equalsIgnoreCase("Y"))
			{
				user.setAdmin(true);
			}
			dao.ofy().put(user);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	 }
	
    public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws IOException {
        
    	res.setContentType("text/plain");

    	/*
    	 * Load the CSV, store as array of strings in the cache, queue the processor
    	 */
    	res.getWriter().println("Loading users.csv");
    	String dataPath = "WEB-INF/data/users.csv";
    	File file = new File(dataPath);
		Scanner scanner = new Scanner(file);
		scanner.nextLine(); // always skip first line of headers
		ArrayList<String> data = new ArrayList<String>();
		while(scanner.hasNextLine())
		{
			String line = scanner.nextLine();
			logger.debug(line);
			data.add(line);
		}
		
		
		// Store the list in cache
		res.getWriter().println("Preparing cache");
		
        res.getWriter().println("Storing CSV data");
        cache.put("csv-user", data);

        // test, get it out again
        res.getWriter().println("Fetching CSV data");
        ArrayList<String> out = (ArrayList<String>) cache.get("csv-user");
        res.getWriter().println("fetched data size=" + out.size());

    	for (int i = 0; i < data.size(); i++) {
    		String taskNotice = "Create task for row("+i+")";
    		res.getWriter().println(taskNotice);
    		logger.debug(taskNotice);
    		Queue queue = QueueFactory.getQueue("load-users");
    		queue.add(TaskOptions.Builder.url(TASK_PATH).method(Method.POST).param("l",Integer.toString(i)));
		}
    	
    	
    }
    
	private Double parseFieldAsDouble(String value)
	{
		Double doubleValue = null;
		try {
			doubleValue = Double.parseDouble(value);
		} catch (Exception e)
		{
			logger.debug(" ("+value+") was not parsed as Double, returning null");
		}
		return doubleValue;
	}
	
	private Integer parseFieldAsInteger(String value)
	{
		Integer integerValue = null;
		try {
			integerValue = Integer.parseInt(value);
		} catch (Exception e)
		{
			logger.debug(" ("+value+") was not parsed as Integer, returning null");
		}
		return integerValue;
	}
	
	private Date parseFieldAsDate(String value)
	{
		Date dateValue = null;
		try {
			dateValue = new Date(value);
		} catch (Exception e)
		{
			logger.debug(" ("+value+") was not parsed as Date, returning null");
		}
		return dateValue;
	}
	
	private String parseFieldAsString(String value)
	{
		return value;
	}	
}
